import os, re, itertools
from pyrem_strs import *

# python-graph (http://code.google.com/p/python-graph/), ver. 1.6.3
from pygraph.classes.digraph import digraph as pg_digraph 
from pygraph.readwrite.dot import write as pg_write

# read source files from current directory
fileTable = FileTable()
fileTable.read_from_directory("", re.compile(".+[.]py$"), recursive=True)
initFiles = [fileTable.pop(p) for p in fileTable.keys() if p.endswith("__init__.py")]

# find identifiers
s = r'[ruRU]*"(\\.|[^"])*"|"""((!?""").)*"""'
pat = re.compile("|".join([r"\b(?P<def>(def|class)\s+)?(?P<id>[a-zA-Z_]\w*)", # identifier
        s, s.replace('"', "'"), r"#[^\n]*\n"])) # string literals, comment
referredIds, definedIds = [], []
for _, ns in sorted(fileTable.iteritems()):
    for m in pat.finditer(origined_str(ns)):
        id = m.group('id')
        if m.group('def'): definedIds.append(id)
        elif id: referredIds.append(id)
referredIds = filter(set(definedIds).__contains__, referredIds)

# build graph of dependency (by name) between the source files
graph = pg_digraph()
graph.add_nodes(ns.name for ns in fileTable.values())
for defName, defs in itertools.groupby(sorted(definedIds)):
    defFiles = [id.origin0.namedstr for id in defs]
    refFiles = [id.origin0.namedstr for id in referredIds if id == defName]
    if not set(refFiles) - set(defFiles): continue # skip if the id is used only in one file
    graph.add_node(defName)
    for edge in set([(defName, f.name) for f in defFiles] + [(f.name, defName) for f in refFiles]):
        graph.add_edge(edge)

# make it power graph
edges, nodes = utility.powergraph.calc_power_digraph(graph.edges(), graph.nodes())
pgraph = pg_digraph()
pgraph.add_nodes(nodes)
for edge in edges: pgraph.add_edge((edge[0], edge[1]))

# draw the graph
def to_label(n): return ",\\n".join(s.replace(os.path.sep, '/') for s in n)
for n in pgraph.nodes():
    pgraph.add_node_attribute(n, ("label", to_label(n)))
    if n[0].endswith(".py"): pgraph.add_node_attribute(n, ("shape", "box"))
file("graph.dot", "w").write(pg_write(pgraph))